package com.example.leakcanary

import android.app.Activity
import android.app.AlertDialog
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.Bundle
import android.os.Handler
import android.os.SystemClock
import android.view.View
import android.widget.Button
import java.util.concurrent.atomic.AtomicReference
import kotlin.random.Random

class MainActivity : Activity() {

    private var leakyReceiver = false

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.main_activity)

        val app = application as ExampleApplication

        findViewById<Button>(R.id.recreate_activity_button).setOnClickListener { recreate() }

        findViewById<Button>(R.id.leak_activity_button).setOnClickListener {
            val leakedView = findViewById<View>(R.id.helper_text)

            when (Random.nextInt(4)) {
                // Leak from application class
                0 -> app.leakedViews.add(leakedView)

                // Leak from Kotlin object singleton
                1 -> LeakingSingleton.leakedViews.add(leakedView)

                2 -> {
                    // Leak from local variable on thread
                    val ref = AtomicReference(this)
                    val thread = Thread {
                        val activity = ref.get()
                        ref.set(null)
                        while (true) {
                            print(activity)
                            SystemClock.sleep(1000)
                        }
                    }
                    thread.name = "Leaking local variables"
                    thread.start()
                }

                // Leak from thread fields
                else -> LeakingThread.thread.leakedViews.add(leakedView)
            }
        }

        findViewById<Button>(R.id.show_dialog_button).setOnClickListener {
            AlertDialog.Builder(this)
                    .setTitle("Leaky dialog")
                    .setPositiveButton("Dismiss and leak dialog") { dialog, _ ->
                        app.leakedDialogs += dialog as AlertDialog
                    }
                    .show()
        }

        findViewById<Button>(R.id.start_service_button).setOnClickListener {
            startService(Intent(this, LeakingService::class.java))
        }

        findViewById<Button>(R.id.leak_receiver_button).setOnClickListener {
            leakyReceiver = true
            recreate()
        }

    }

    class NoOpBroadcastReceiver : BroadcastReceiver() {
        override fun onReceive(
                context: Context,
                intent: Intent
        ) = Unit
    }

    override fun onDestroy() {
        super.onDestroy()
        if (leakyReceiver) {
            Handler().postDelayed({
                registerReceiver(NoOpBroadcastReceiver(), IntentFilter())
            }, 500)
        }
    }
}
